/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.mlbs.servlet;

import com.mlbs.entity.Application;
import com.mlbs.entity.Credential;
import com.mlbs.entity.Device;
import com.mlbs.entity.Devicelocation;
import com.mlbs.entity.Pagecache;
import com.mlbs.entity.Preferences;
import com.mlbs.entity.Usertable;
import com.mlbs.session.generated.ApplicationFacadeRemote;
import com.mlbs.session.generated.DeviceFacadeRemote;
import com.mlbs.session.generated.DevicelocationFacadeRemote;
import com.mlbs.session.generated.PagecacheFacadeRemote;
import com.mlbs.session.generated.PreferencesFacadeRemote;
import com.mlbs.utility.GoogleParser;
import com.mlbs.utility.YahooParser;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author mckd87
 */
public class MlbsServlet extends HttpServlet {
    @EJB
    private DevicelocationFacadeRemote devicelocationFacade;

    @EJB
    private ApplicationFacadeRemote applicationFacade;
    @EJB
    private PagecacheFacadeRemote pagecacheFacade;
    @EJB
    private PreferencesFacadeRemote preferencesFacade;
    @EJB
    private DeviceFacadeRemote deviceFacade;

    /** 
    * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
    * 
    * Usage: http://localhost:8080/MLBSWebApp/MlbsServlet
    *  
    * @param request servlet request
    * @param response servlet response
    */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            System.out.println(request.getAttribute("query"));
            String latitude = request.getParameter("latitude");
            String longitude = request.getParameter("longitude");
            String city = request.getParameter("city");
            String state = request.getParameter("state");
            String query = request.getParameter("query");
            String zip = request.getParameter("zip");
            String imei = request.getParameter("IMEI");
            String cache = request.getParameter("cache");
            String privacy = request.getParameter("privacy");
            String appId =  request.getParameter("appId");
            String invoice =  request.getParameter("invoice");
            String fromDate =  request.getParameter("start");
            String toDate =  request.getParameter("end");
            
            if(invoice != null){
                getInvoiceForDevice(out, imei, fromDate, toDate);
                return;
            }
            
            // To test caching, pass query=testCache
            // To test privacy, pass query=testPrivacy
            if(cache != null && cache.length()>0){
                if(query == null){
                    out.println("Updating users CacheSettings: "+ cache);
                    updateCacheSettings(imei, cache);
                }else{
                    //out.println("testing users cacheSettings: "+ cache);
                    testCaching(out, imei, cache, appId);
                }
            }else if(privacy != null && privacy.length()>0){
                if(query == null){
                    out.println("Updating users PrivacySettings: "+ privacy);
                    updatePrivacySettings(imei, "privacy", privacy);
                }else{
                    out.println("testing users PrivacySettings: "+ privacy);
                    testPrivacy(out, imei, privacy, appId);
                }                
            }else if((query == null || query.length()==0) && imei == null){
                response.setContentType("text/html");
                Enumeration e = request.getHeaderNames();
                out.println("<html>");
                out.println("<head>");
                out.println("<title>Mlbs Phone detector</title>");  
                out.println("</head>");
                out.println("<body>");
                while (e.hasMoreElements()) {
                    String name = (String)e.nextElement();
                    String value = request.getHeader(name);
                    if(! name.startsWith("accept"))
                        out.println(name + " = " + value + "<br>");
                }
                out.println("</body>");
                out.println("</html>");
            }
            else if(query != null){
                try {
                    // Construct data
                    StringBuffer urlStr = new StringBuffer("http://local.yahooapis.com/LocalSearchService/V3/localSearch");
                    urlStr.append("?appid=YahooDemo");
                    urlStr.append("&query="+URLEncoder.encode(query, "UTF-8"));
                    if(latitude!=null && latitude.length()>0)
                        urlStr.append("&latitude="+latitude);
                    if(longitude!=null && longitude.length()>0)
                        urlStr.append("&longitude="+longitude);
                    if(city !=null && city.length()>0)
                        urlStr.append("&city="+URLEncoder.encode(city, "UTF-8"));
                    if(state!=null && state.length()>0)
                        urlStr.append("&state="+state);
                    if(zip !=null && zip.length()>0)
                        urlStr.append("&zip="+zip);
                    urlStr.append("&results=3");
                    urlStr.append("&radius=2");

                    // Send data
                    //URL url = new URL("http://localhost:8080/MLBSWebApp/MlbsServlet");
                    URL url = new URL(urlStr.toString());
                    URLConnection conn = url.openConnection();

                    conn.setDoOutput(true);
                    
                    // Get the response
                    YahooParser parser = new YahooParser(conn.getInputStream());
                    parser.parseXML();
                    ArrayList res = (ArrayList)parser.getResults();
                    System.out.println(res.size());
                    String cityName = null;
                    String stateName = null;
                    String streetAddress = null;
                    boolean storeLoc = false;
                    for(int i=0;i<res.size();i++){
                        HashMap hm = (HashMap)res.get(i);
                        out.print(";Result - ");
                        out.print(i+1);out.println(";");
                        Set set = hm.keySet();
                        Iterator itr = set.iterator();
                        
                        while(itr.hasNext()){
                            String key = (String) itr.next();
                            out.print(key);
                            out.print("=");
                            out.println((String)hm.get(key)+";;");
                            if(key.equalsIgnoreCase("city")){
                                cityName = (String)hm.get(key);
                            }else if(key.equalsIgnoreCase("state")){
                                stateName = (String)hm.get(key);
                            }else if(key.equalsIgnoreCase("address")){
                                streetAddress = (String)hm.get(key);
                            }
                            out.println(" ");
                        }
                       if(!storeLoc && cityName != null && stateName != null && streetAddress != null){
                           storeLoc = true;
                           storeLocationData(cityName, stateName, streetAddress, latitude, longitude, imei);
                       }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else if(imei != null){
                String password = request.getParameter("PassWord");
                Device device = deviceFacade.find(imei);
                Usertable user = device.getUserid();
                Credential credential = user.getCredential();
                if(credential.getPassword().equalsIgnoreCase(password)){
                    out.println("Authentication successfull for "+user.getDisplayName());
                }else
                {
                    out.println("Authentication failed !");
                }
            }
        } catch(Exception e){
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
        }
        
        
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
    * Handles the HTTP <code>GET</code> method.
    * @param request servlet request
    * @param response servlet response
    */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    /** 
    * Handles the HTTP <code>POST</code> method.
    * @param request servlet request
    * @param response servlet response
    */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
    * Returns a short description of the servlet.
    */
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    private void getInvoiceForDevice(PrintWriter out, String imei, String fromDate, String toDate) {
        
    }
    private String getNewsFeed() {
        String urlStr = "http://news.google.com/?output=rss";
        try{
            URL url = new URL(urlStr.toString());
            URLConnection conn = url.openConnection();
            conn.setDoOutput(true);
            String userAgent = "Mozilla/2.02Gold (WinNT;I)";
            conn.setRequestProperty("USER-AGENT", userAgent);        
            // Get the response
            GoogleParser parser = new GoogleParser(conn.getInputStream());
            parser.parseXML();
            ArrayList res = (ArrayList)parser.getResults();
            System.out.println(res.size());
            StringBuffer buff = new StringBuffer();
            for(int i=0;i<3;i++){
                buff.append(res.get(i));
                if(i!=(res.size()-1))
                    buff.append("; ");
            }
            return buff.toString();
        }catch(Exception e){
            e.printStackTrace();
        }
        return "Bush Signs Measure for Homeowners Fannie Freddie (Update2) - Bloomberg, Turkey’s Governing Party Avoids Ban - New York Times" +
                ", Zimbabwe talks set to resume Sunday: Mbeki - AFP";
    }

    private void storeLocationData(String cityName, String stateName, String streetAddress, String latitude, String longitude, String imei) {
        //throw new UnsupportedOperationException("Not yet implemented");
        devicelocationFacade.setDeviceLocation(cityName, stateName, streetAddress, latitude, longitude, imei);
    }
    private void testCaching(PrintWriter out, String imei, String cache, String appId) {
        //throw new UnsupportedOperationException("Not yet implemented");
        Application app = applicationFacade.find(new Integer(appId));
        if(app == null){
            app = new Application(new Integer(appId));
            app.setApplicationName("FriendFinder");
            app.setDescription("Test App");
            app.setOwner("MLBS");
            applicationFacade.create(app);
        }
        Device device = deviceFacade.find(imei);
        Usertable user = device.getUserid();
        Collection coll = device.getPreferencesCollection();
        System.out.println("Pref of Device " + coll.size());
        Collection pageCache;
        Iterator i = coll.iterator();
        while(i.hasNext()){
            Preferences preferences = (Preferences)i.next();
            if(preferences.getAppId() == null){
                preferences.setAppId(app);
                preferencesFacade.edit(preferences);
            }
            if(preferences.getKeyName().equalsIgnoreCase("cache")){
                if(cache.equalsIgnoreCase("enable")){
                    pageCache = preferences.getPagecacheCollection();
                    System.out.println("Size of page cache"+pageCache.size());
                    Iterator ii = pageCache.iterator();
                    while(ii.hasNext()){
                        Pagecache pc = (Pagecache)ii.next();
                        if(pc.getCacheIndex().intValue() == 0){
                            System.out.println("From CACHE");
                            out.println(pc.getPageValue());
                            break;
                        }
                    }
                }else{
                      String newsFeed = getNewsFeed();
                      pageCache = preferences.getPagecacheCollection();
                      if(pageCache.size()>0){
                          Iterator ii = pageCache.iterator();
                          while(ii.hasNext()){
                              Pagecache pc = (Pagecache)ii.next();
                              if(pc.getCacheIndex().intValue() == 0){
                                  pc.setPageValue(newsFeed);
                                  pc.setPage(newsFeed);
                                  pc.setDateCreated(new Date(System.currentTimeMillis()));
                                  pagecacheFacade.edit(pc);
                                  out.println(newsFeed);
                                  System.out.println("From Source, updating cache");
                                  break;
                              }
                          }
                      }else{
                          Pagecache pc = new Pagecache(new Integer("0"));
                          pc.setCacheIndex(new Integer(0));
                          pc.setDateCreated(new Date(System.currentTimeMillis()));
                          pc.setDeviceId(device);
                          pc.setPage(newsFeed);
                          pc.setPageValue(newsFeed);
                          //pc.setAppId1(app);
                          pc.setAppId(preferences);
                          pagecacheFacade.create(pc);
                          out.println(newsFeed);
                          System.out.println("From Source, creating cache");
                      }
                }
            }
        }
    }

    private void testPrivacy(PrintWriter out, String imei, String privacy, String appId) {
        if(privacy.equalsIgnoreCase("disable")){
            out.println("Location can not be shared");
        }else{
            Device device = deviceFacade.find(imei);
            //Usertable user = device.getUserid();
            Devicelocation loc = device.getDevicelocation();
            
            System.out.println("Location of  "+device.getUserid().getDisplayName()+ " is " +loc.getStreet()+","+loc.getCity()+ ", "+loc.getState());
            out.println("Location of  "+device.getUserid().getDisplayName()+ " is " +loc.getStreet()+","+loc.getCity()+ ", "+loc.getState());
        }
    }

    private void updateCacheSettings(String imei, String cache) {
        preferencesFacade.updateCacheSettings(imei, cache);
    }

    private void updatePrivacySettings(String imei, String key, String value) {
        preferencesFacade.updatePreferences(imei, key, value);
    }

}
